package org.chatboleh.bean;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.chatboleh.exception.EDMException;

public class Page extends DataObject implements Printable {
	private List<TextElement> textelementlist;
	private int imageableX;
	private int imageableY;
	private int imageableWidth;
	private int imageableHeight;
	private int pageHeightInch;
	private int pageWidthInch;

	public Page() {
		textelementlist = new ArrayList<TextElement>();
		imageableX = 0;
		imageableY = 0;
		imageableWidth = 400;
		imageableHeight = 200;
		pageWidthInch = 500;
		pageHeightInch = 500;
	}

	public Page(long id) {
		super(id);
		this.loadTextelementlist();
	}

	private void loadTextelementlist() {
		try {
			textelementlist = new Page_TextElement().getList("page.id="
					+ this.id);
		} catch (EDMException e) {
			logger.error(e);
		}
	}

	@Override
	protected String fieldnames() {
		return "pageWidthInch,pageHeightInch,imageableX,imageableY,imageableWidth,imageableHeight";
	}

	@Override
	public List<Page> getList(String criteria) throws EDMException {
		List<Page> list = new ArrayList<Page>();

		try {
			openConnection();
			prepareStatement(selectlistquery(criteria));
			executeQuery();
			while (resultset.next()) {
				Page page = new Page();
				page.id = resultset.getLong("id");
				page.loadResultSetIntoObject(resultset);
				list.add(page);
			}
		} catch (SQLException e) {
			throw new EDMException(e);
		} finally {
			closeStatement();
		}
		return list;
	}

	@Override
	protected void loadResultSetIntoObject(ResultSet resultset) {
		try {
			this.pageWidthInch = resultset.getInt("pageWidthInch");
			this.pageHeightInch = resultset.getInt("pageHeightInch");
			this.imageableX = resultset.getInt("imageableX");
			this.imageableY = resultset.getInt("imageableY");
			this.imageableWidth = resultset.getInt("imageableWidth");
			this.imageableHeight = resultset.getInt("imageableHeight");
		} catch (SQLException e) {
			logger.error(e);
		}
	}

	@Override
	public void prepareUpdate() throws EDMException {
		try {
			ps.setInt(1, this.pageWidthInch);
			ps.setInt(2, this.pageHeightInch);
			ps.setInt(3, this.imageableX);
			ps.setInt(4, this.imageableY);
			ps.setInt(5, this.imageableWidth);
			ps.setInt(6, this.imageableHeight);
		} catch (SQLException e) {
			throw new EDMException(e);
		}
	}

	@Override
	protected String tablename() {
		return "page";
	}

	@Override
	public int print(Graphics g, PageFormat pf, int page)
			throws PrinterException {
		logger.debug("Printing page: " + page);
		logger.debug("Old PageWidth = " + pf.getWidth());
		logger.debug("Old PageHeight = " + pf.getHeight());
		Paper paper = new Paper();
		paper.setImageableArea(this.imageableX, this.imageableY,
				this.imageableWidth, this.imageableHeight);
		paper.setSize(this.pageWidthInch * 72, this.pageHeightInch * 72);
		pf.setPaper(paper);

		logger.debug("New PageWidth = " + pf.getWidth());
		logger.debug("New PageHeight = " + pf.getHeight());
		if (page > 0) { /* We have only one page, and 'page' is zero-based */
			return NO_SUCH_PAGE;
		}

		/*
		 * User (0,0) is typically outside the imageable area, so we must
		 * translate by the X and Y values in the PageFormat to avoid clipping
		 */
		Graphics2D g2d = (Graphics2D) g;
		g2d.translate(pf.getImageableX(), pf.getImageableY());

		/* Now we perform our rendering */

		// remove this later
		logger.debug("Drawing Rect.");
		g2d.drawRect(this.imageableX, this.imageableY, this.imageableWidth,
				this.imageableHeight);
		for (int i = 0; i < textelementlist.size(); i++) {
			TextElement te = textelementlist.get(i);
			logger.debug("Printing > " + te.getText());
			g2d.setColor(te.getFontColor());
			g2d.setFont(new Font(te.getFontName(), te.getFontStyle(), te
					.getFontSize()));
			g2d.drawString(te.getText(), te.getX(), te.getY());

		}
		logger.debug("Finish Printing\n.");
		/* tell the caller that this page is part of the printed document */
		return PAGE_EXISTS;

	}

	@Override
	public void save() throws EDMException {
		super.save();
		for (TextElement textelement : textelementlist) {
			textelement.save();
			PageTextElement page_textelement = new PageTextElement();
			page_textelement.setPageid((int) this.id);
			page_textelement.setTextelementid((int) textelement.id);
			page_textelement.save();
		}
	}

	@Override
	public void delete() throws EDMException {
		List<PageTextElement> page_textelement_list = new PageTextElement()
				.getList("pageid=" + this.id);
		for (PageTextElement pageTextElement : page_textelement_list) {
			pageTextElement.delete();
		}
		page_textelement_list.clear();
		for (TextElement textelement : textelementlist) {
			textelement.delete();
		}
		textelementlist.clear();
		super.delete();
	}

	public List<TextElement> getTextelementlist() {
		return textelementlist;
	}

	public void setTextelementlist(List<TextElement> textelementlist) {
		this.textelementlist = textelementlist;
	}

	public void addTextElement(TextElement textelement) {
		this.textelementlist.add(textelement);
	}

	public int getImageableX() {
		return imageableX;
	}

	public void setImageableX(int imageableX) {
		this.imageableX = imageableX;
	}

	public int getImageableY() {
		return imageableY;
	}

	public void setImageableY(int imageableY) {
		this.imageableY = imageableY;
	}

	public int getImageableWidth() {
		return imageableWidth;
	}

	public void setImageableWidth(int imageableWidth) {
		this.imageableWidth = imageableWidth;
	}

	public int getImageableHeight() {
		return imageableHeight;
	}

	public void setImageableHeight(int imageableHeight) {
		this.imageableHeight = imageableHeight;
	}

	public int getPageHeightInch() {
		return pageHeightInch;
	}

	public void setPageHeightInch(int pageHeightInch) {
		this.pageHeightInch = pageHeightInch;
	}

	public int getPageWidthInch() {
		return pageWidthInch;
	}

	public void setPageWidthInch(int pageWidthInch) {
		this.pageWidthInch = pageWidthInch;
	}

}
